#pragma once
#include "Runtime/CGI/CGIRenderTarget.h"
#include "VulkanRenderTarget.h"
#include "VulkanTexture.h"
#include "VulkanView.h"

namespace Alice
{
    class VulkanFramebuffer
    {
    public:
        const VulkanRenderPass* mRenderPass;
        VkImageView mColorAttachment0ImageView;
        VulkanFramebuffer(VulkanDevice& Device, const CGISetRenderTargetsInfo& InRTInfo, const VulkanRenderTargetLayout& RTLayout, const VulkanRenderPass& RenderPass);
        ~VulkanFramebuffer();

        bool Matches(const CGISetRenderTargetsInfo& RTInfo) const;

        uint32 GetNumColorAttachments() const
        {
            return NumColorAttachments;
        }

        void Destroy(VulkanDevice& Device);

        VkFramebuffer GetHandle()
        {
            return Framebuffer;
        }

        bool ContainsRenderTarget(CGITexture* Texture) const
        {
            CGIVulkanTexture* VulkanTexture = reinterpret_cast<CGIVulkanTexture*>(Texture);
            return ContainsRenderTarget(VulkanTexture->mImage);
        }

        bool ContainsRenderTarget(VkImage Image) const
        {
            for (uint32 Index = 0; Index < NumColorAttachments; ++Index)
            {
                if (ColorRenderTargetImages[Index] == Image)
                {
                    return true;
                }
            }

            return (DepthStencilRenderTargetImage == Image);
        }

        VkRect2D GetRenderArea() const
        {
            return RenderArea;
        }

    private:
        VkFramebuffer Framebuffer;
        VkRect2D RenderArea;

        // Unadjusted number of color render targets as in FRHISetRenderTargetsInfo 
        uint32 NumColorRenderTargets;

        // Save image off for comparison, in case it gets aliased.
        uint32 NumColorAttachments;
        VkImage ColorRenderTargetImages[MaxSimultaneousRenderTargets];
        VkImage ColorResolveTargetImages[MaxSimultaneousRenderTargets];
        VkImage DepthStencilRenderTargetImage;
        VkImage DepthStencilResolveRenderTargetImage;
        VkImage FragmentDensityImage;

        // Predefined set of barriers, when executes ensuring all writes are finished
        std::vector<VkImageMemoryBarrier> WriteBarriers;
        std::vector<CGIVulkanView> OwnedTextureViews;
        std::vector<CGIVulkanView const*> AttachmentTextureViews;
        friend class FVulkanCommandListContext;
    };
}
